package com.xiaoshuidi.cloud.module.rooms.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaoshuidi.cloud.module.rooms.controller.admin.rentalspace.vo.*;
import com.xiaoshuidi.cloud.module.rooms.convert.rentalspace.RentalSpaceConvert;
import com.xiaoshuidi.cloud.module.rooms.enums.RentSpaceRentStatusEnum;
import com.xiaoshuidi.cloud.module.rooms.enums.RentSpaceTypeEnum;
import com.xiaoshuidi.cloud.module.rooms.framework.utils.CodeUtil;
import com.xiaoshuidi.cloud.module.rooms.mapper.RentalSpaceMapper;
import com.xiaoshuidi.cloud.module.rooms.pojo.RoomRentalSpace;
import com.xiaoshuidi.cloud.module.rooms.pojo.roomel.RentalSpaceelEntity;
import com.xiaoshuidi.cloud.module.rooms.repository.irepository.IRentalSpaceRepository;
import com.xiaoshuidi.cloud.module.rooms.service.IRentalSpaceService;
import com.xiaoshuidi.cloud.module.rooms.service.RentalSpaceEsclientService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.zxp.esclientrhl.enums.AggsType;
import org.zxp.esclientrhl.repository.ElasticsearchTemplate;
import org.zxp.esclientrhl.repository.PageList;
import org.zxp.esclientrhl.repository.PageSortHighLight;
import org.zxp.esclientrhl.repository.Sort;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@RequiredArgsConstructor
public class RentalSpaceServiceImpl extends ServiceImpl<RentalSpaceMapper, RoomRentalSpace> implements IRentalSpaceService {

    @Autowired
    private RentalSpaceEsclientService esclientService;

    @Autowired
    ElasticsearchTemplate<RentalSpaceelEntity,Integer> elasticsearchTemplate;

    @Resource
    private IRentalSpaceRepository iRentalSpaceRepository;

    private final CodeUtil codeUtil;

    @Override
    public Boolean listadd(List<RentalSpaceCreateReqVO> reqVOS) {
        log.info("RentalSpaceEsclientService接收到的参数为："+reqVOS.toString());

        List<RentalSpaceelEntity> entityList = RentalSpaceConvert.INSTANCE.convertList(reqVOS);
        log.info("转换后的参数为："+entityList.toString());
        try {
            BulkResponse result = esclientService.save(entityList);
            //true:全部成功  false:有失败的
            Boolean resultflag = !result.hasFailures();
            log.info("空间租赁推送es接口-新增:"+resultflag);
            return resultflag;
        } catch (Exception e) {
            log.error("空间租赁推送es接口-新增:报错",e);
            throw new RuntimeException(e);
        }
    }

    @Override
    public PageList<RentalSpaceelEntity> queryPage(int currentPage, int pageSize, String searchbox,Long id,String name,Long apartmentId,String type,String rentStatus) {

        RentalSpaceBaseVO reqVO = new RentalSpaceBaseVO();
        reqVO.setId(id);
        reqVO.setName(name);
        reqVO.setApartmentId(apartmentId);
        reqVO.setType(type);
        reqVO.setRentStatus(rentStatus);

        PageList<RentalSpaceQueryRespVO> rvolist = new PageList<>();
        PageList<RentalSpaceelEntity> search = new PageList<>();

        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        //封装筛选条件
        queryBuilder = addRentalFilter(queryBuilder,reqVO,searchbox);

        //排序
        Sort sort = new Sort(new Sort.Order(SortOrder.ASC,"id"));
        //分页
        PageSortHighLight psh = new PageSortHighLight(currentPage,pageSize,sort);

        try {
            search = esclientService.search(queryBuilder, psh);
        } catch (Exception e) {
            log.error("房源信息推送es接口-分页查询:报错",e);
            throw new RuntimeException(e);
        }
        return search;

    }

    @Override
    public Long addRentalSpace(RentalSpaceCreateReqVO reqVO) {
        //固定传参
        reqVO.setProvince("安徽省");
        reqVO.setCity("合肥市");
        reqVO.setRentStatus("1");
        reqVO.setArea(reqVO.getAddress());
        reqVO.setMonthRental(0D);
        //生成 id和空间编号
        if( StrUtil.isEmpty(reqVO.getType()) || StrUtil.isBlank( RentSpaceTypeEnum.getSpaceNoLastByValue(reqVO.getType()) )){
            throw new IllegalArgumentException("未知的空间类型");
        }
        reqVO.setSpaceNo(codeUtil.nextCode(RentSpaceTypeEnum.getSpaceNoLastByValue(reqVO.getType())));


        RoomRentalSpace roomRentalSpace = RentalSpaceConvert.INSTANCE.convert2(reqVO);
        iRentalSpaceRepository.save(roomRentalSpace);
        return roomRentalSpace.getId();

    }

    @Override
    public Boolean updateRentalSpace(RentalSpaceUpdateReqVO reqVO) {
        if(ObjectUtil.isEmpty( reqVO.getId() )){
            throw new IllegalArgumentException("id不能为空");
        }

        validateRentalSpaceExists(reqVO.getId());
        RoomRentalSpace roomRentalSpace = RentalSpaceConvert.INSTANCE.convert2(reqVO);
        return iRentalSpaceRepository.updateById(roomRentalSpace);
    }

    @Override
    public Boolean updateEs(RentalSpaceUpdateReqVO reqVO) {
        log.info("接收到的参数为："+reqVO.toString());
        RentalSpaceelEntity entity = RentalSpaceConvert.INSTANCE.convert(reqVO);
        log.info("转换后的参数为："+entity.toString());

        boolean result = false;
        try {
            //部分更新，只更新不为空的字段
            result = elasticsearchTemplate.update(entity);
        } catch (Exception e) {
            log.error("房源信息推送es接口-根据es的id更新房源:报错",e);
            throw new RuntimeException(e);
        }
        return result;
    }

    @Override
    public Map<String, Object> queryHouseStateSum(String searchbox,Long id,String name,Long apartmentId,String type) {
        RentalSpaceBaseVO reqVO = new RentalSpaceBaseVO();
        reqVO.setId(id);
        reqVO.setName(name);
        reqVO.setApartmentId(apartmentId);
        reqVO.setType(type);

        Map search = new HashMap();
        Map ret = new HashMap<>();

        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        //封装筛选条件
        queryBuilder = addRentalFilter(queryBuilder,reqVO,searchbox);

        try {
            search = esclientService.aggs("id", AggsType.count, queryBuilder, "rentStatus.keyword");

            log.info(search.toString());
        } catch (Exception e) {
            log.error("Es租赁空间房态计数查询报错！",e);
            throw new RuntimeException(e);
        }

        //封装 根据房态枚举类，来自动封装Map
        log.info("根据租赁空间，来自动封装Map----------");
        RentSpaceRentStatusEnum[] values = RentSpaceRentStatusEnum.values();
        Long sumval = 0L;
        for (RentSpaceRentStatusEnum value : values) {
            Object searchval = search.get(value.getValue());
            log.info(value.getName()+"："+value.getValue()+":"+searchval);
            if(ObjectUtil.isNotEmpty(searchval)){
                ret.put(value.getValue() , searchval );
                sumval += (Long)searchval;
            }else{
                ret.put(value.getValue() , 0L );
            }
        }
        ret.put("allsum",sumval);

        return ret;
    }

    @Override
    public List<RentalSpaceExportRespVO> exportRentalSpace(RentalSpaceExportReqVO exportReqVO) {

        List<RoomRentalSpace> list = iRentalSpaceRepository.exportRentalSpace(exportReqVO);
        return RentalSpaceConvert.INSTANCE.convertList3(list);
    }

    @Override
    public RoomRentalSpace queryById(Integer id) {

        if (ObjectUtil.isEmpty(id)) {
            throw new IllegalArgumentException("传入的id不能为空！");
        }
        return iRentalSpaceRepository.getById(id);

    }

    @Override
    public Boolean deleteByid(Integer id) {
        return iRentalSpaceRepository.removeById(id);
    }

    @Override
    public Boolean deleteESByid(Integer id) {

        boolean result = false;
        try {
            result = elasticsearchTemplate.deleteById(id, RentalSpaceelEntity.class);
        } catch (Exception e) {
            log.error("房源信息推送es接口-根据es的id删除房源:报错",e);
            throw new RuntimeException(e);
        }
        return result;
    }


    //校验数据库是否存在
    private void validateRentalSpaceExists(Long id) {
        if (iRentalSpaceRepository.getById(id) == null) {
            throw new IllegalArgumentException("数据库不存在这条数据id："+id);
        }
    }

    //ES查询条件封装
    BoolQueryBuilder addRentalFilter(BoolQueryBuilder queryBuilder, RentalSpaceBaseVO reqVO,String searchbox){

        //房间id
        if(!StringUtils.isEmpty(reqVO.getId())){
            queryBuilder.must( QueryBuilders.termQuery("id",reqVO.getId()) );
        }

        //公寓id
        if(!StringUtils.isEmpty(reqVO.getApartmentId())){
            queryBuilder.must( QueryBuilders.termQuery("apartmentId",reqVO.getApartmentId()) );
        }
        //类型 商铺、办公室、其他
        if(!StringUtils.isEmpty(reqVO.getType())){
            queryBuilder.must( QueryBuilders.termQuery("type",reqVO.getType()) );
        }
        //rentStatus  房态
        if(!StringUtils.isEmpty(reqVO.getRentStatus())){
            queryBuilder.must( QueryBuilders.termQuery("rentStatus",reqVO.getRentStatus()) );
        }
        //搜索框-分词搜索-空间名字 承租人 手机号
        if(!StringUtils.isEmpty(searchbox)) {
            QueryBuilder queryBuilderbox = QueryBuilders.multiMatchQuery(searchbox, "name","tenantMainName","tenantMainPho");
            queryBuilder.must(queryBuilderbox);
        }
        return queryBuilder;
    }

}
